package com;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class ChargenServer {

    private final static int DEFAULT_PORT = 1119;

    private final static int SHOW_NUM = 72;

    private final static int ALL_NUM = 95;

    private int port;

    public ChargenServer(int port) {
        this.port = port;
    }

    public void start() throws IOException {

        System.out.println("Listen on port: " + port);

        byte[] rotation = new byte[ALL_NUM*2];

        for(byte i=' ';i<='~';i++){
            rotation[i-' '] = i;
            rotation[i+ALL_NUM-' '] = i;
        }

        ServerSocketChannel server = ServerSocketChannel.open();

        InetSocketAddress addr = new InetSocketAddress(port);

        server.bind(addr);

        server.configureBlocking(false);

        Selector selector = Selector.open();

        server.register(selector, SelectionKey.OP_ACCEPT);



        while (true){

            try {


                selector.select();

                Set<SelectionKey> readyKey = selector.selectedKeys();

                Iterator<SelectionKey> iter = readyKey.iterator();

                while (iter.hasNext()) {

                    SelectionKey key = iter.next();

                    iter.remove();

                    if (key.isAcceptable()) {
                        //接收新连接并注册
                        ServerSocketChannel channel = (ServerSocketChannel) key.channel();

                        SocketChannel client = channel.accept();

                        System.out.println(client + " has conneted on");

                        client.configureBlocking(false);

                        SelectionKey key2 = client.register(selector, SelectionKey.OP_WRITE);

                        ByteBuffer buffer = ByteBuffer.allocate(SHOW_NUM + 2);

                        buffer.put(rotation, 0, SHOW_NUM);

                        buffer.put((byte) '\r');

                        buffer.put((byte) '\n');

                        buffer.flip();

                        key2.attach(buffer);
                    }
                    if (key.isWritable()) {
                        //可写，客户端事件
                        SocketChannel client = (SocketChannel) key.channel();

                        ByteBuffer buffer = (ByteBuffer) key.attachment();

                        if (!buffer.hasRemaining()) {

                            buffer.rewind();

                            int first = buffer.get();

                            buffer.rewind();

                            int position = first - ' ' + 1;

                            buffer.put(rotation, position, SHOW_NUM);

                            buffer.put((byte) '\r');

                            buffer.put((byte) '\n');

                            buffer.flip();
                        }

                        client.write(buffer);

                    }

                }
            }catch (IOException ex){

//                if(ex.getMessage().equals("Broken pipe")){
//                    continue;
//                }

            }

        }

    }

    public static void main(String[] args) {

        int port;

        if(args.length == 0){
            port = DEFAULT_PORT;
        }else{
            port = Integer.parseInt(args[0]);
        }

        ChargenServer server = new ChargenServer(port);

        try {
            server.start();
        } catch (IOException e) {
            e.getMessage();
        }

    }

}
